<?php

/**
 * 绮梦PHP框架 (Dream PHP Freamework)
 * 免费 简单 快速 高效 安全 专业
 * 绮梦PHP框架是一个基于组件的PHP框架，用于快速开发现代Web应用程序。
 *
 * @author lewis (lewisld@163.com)
 * @copyright Copyright (c) 2015, lewis (http://www.dreamfreamework.com/)
 * @license http://www.dreamfreamework.com/licenses/ Apache License
 * @link http://www.dreamfreamework.com/
 */

namespace System\Basic;

use System\Exception\InvalidPropertyCallException;
use System\Exception\InvalidMethodCallException;

/**
 * 基类
 * 这是所有类的基类
 *
 * @package Dream
 * @subpackage Object
 * @namespace System\Basic
 * @author lewis (lewisld@yeah.net)
 */
class Object
{

    /**
     * 对象实例列表
     *
     * @static
     * @access protected
     * @var object
     */
    protected static $instance = null;

    /**
     * 构造方法
     */
    public function __construct()
    {
        $this->initialize(implode(', ', func_get_args()));
        self::init(implode(', ', func_get_args()));
    }

    /**
     * 初始化（静态）
     *
     * @static
     *
     * @access public
     * @return \System\Basic\Object
     */
    public static function init()
    {
        return self::getInstance(implode(', ', func_get_args()));
    }

    /**
     * 初始化（动态）
     *
     * @access public
     * @return \System\Basic\Object
     */
    public function initialize()
    {
        return $this->getInstance(implode(', ', func_get_args()));
    }

    /**
     * 实例化类并获取它的实例
     *
     * @static
     * @access public
     * @return \System\Basic\Object 返回实例化后的对象
     */
    public static function getInstance()
    {
        if (null === self::$instance || !is_object(self::$instance)) {
            self::$instance = new self(implode(', ', func_get_args()));
        }
        self::$instance->__instance();
        return self::$instance;
    }

    /**
     * 获取静态方法调用的类名
     *
     * @static
     *
     * @access public
     * @return string 返回静态类名
     */
    public static function getClassName()
    {
        return get_called_class();
    }

    /**
     * 获取一个对象属性的值
     *
     * @param string $name 对象属性名称
     * @throws InvalidPropertyCallException 无效的属性调用异常
     */
    public function __get($name)
    {
        if (method_exists($this, 'getProperty')) {
            $this->$setter($name);
        } else {
            throw new InvalidPropertyCallException([
                'error.object.invalid.property.call',
                [
                    'class' => get_class($this),
                    'method' => 'getProperty',
                    'param' => $name
                ]
            ]);
        }
    }

    /**
     * 设置一个对象的属性值
     *
     * @param string $name 对象属性名称
     * @param mixed $value 对象属性值
     * @throws InvalidPropertyCallException 无效的属性调用异常
     */
    public function __set($name, $value)
    {
        if (method_exists($this, 'setProperty')) {
            $this->$setter($name, $value);
        } else {
            throw new InvalidPropertyCallException([
                'error.object.invalid.property.call',
                [
                    'class' => get_class($this),
                    'method' => 'setProperty',
                    'param' => $name . ',' . $value
                ]
            ]);
        }
    }

    public function __isset($name)
    {
        $getter = 'get' . ucwords($name);
        if (method_exists($this, $getter)) {
            return $this->$getter() !== null;
        } else {
            return false;
        }
    }

    public function __unset($name)
    {
        $setter = 'set' . ucwords($name);
        if (method_exists($this, $setter)) {
            $this->$setter(null);
        }
    }

    public function __call($method, $params)
    {
        throw new InvalidMethodCallException([
            'system.error.object.invalid.method.call',
            [
                'class' => get_class($this),
                'method' => $method,
                'param' => $params
            ]
        ]);
    }

    public static function __callStatic($method, $params)
    {
        throw new InvalidMethodCallException([
            'system.error.object.invalid.static.method.call',
            [
                'class' => get_class(self),
                'method' => $method,
                'param' => $params
            ]
        ]);
    }

    public function __instance()
    {

    }

    public function existMethod($name)
    {
        return method_exists($this, $name);
    }

    public static function existStaticMethod($name)
    {
        return method_exists(self, $name);
    }
}